﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Core.Mvc.Framework.Action;

namespace Core.Mvc.Framework
{
    public abstract class Controller : IController
    {
        public ActionResult Excute(ActionRequest actionRequest)
        {
            ActionResult result = null;
            try
            {
                result = InvokeMethod(actionRequest.Action, this, actionRequest.Args);
                result.Id = actionRequest.Id;
            }
            catch (System.Exception e)
            {
                throw e.InnerException;
            }

           return result;
        }

        public virtual ActionResult View(String name, String action, params object[] parameters)
        {
            ActionResult result = new ActionResult();
            result.View = name;
            try
            {
                IView view = MvcFramwork.GetView(name);
                if (view == null)
                {
                    return result;
                }
               
                if (view.AsychInvoker != null && view.AsychInvoker.InvokeRequired)
                {
                    view.AsychInvoker.BeginInvoke(new RenderHandler(delegate
                    {
                        result = InvokeMethod(action, view, parameters);
                    }), new Object[] { });
                }
                else
                {
                    result = InvokeMethod(action, view, parameters);
                    if (result == null)
                    {
                        throw new Exception("View implementation must return as ActionResult!");
                    }
                    result.View = name;
                }
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
           
            return result;
        }

        protected virtual ActionResult InvokeMethod(String name, Object invokeObj, params object[] parameters)
        {
            return invokeObj.GetType().InvokeMember(name, BindingFlags.InvokeMethod, null, invokeObj, parameters) as ActionResult;
        }
    }
}
